<?php

/**
 * This file is part of the Anota project.
 * 2011-2012 Fernando Garcia Huerta <fgarciahue@uoc.edu>
 * 
 * UOC - FUNDAMENTOS DE INFORMÁTICA EN ENTORNOS BIOINFORMÁTICOS - PEC2
 */

/**
 * Annotate Module
 *
 * @package    Anota
 * @subpackage application/module
 * @author     Fernando Garcia Huerta <fgarciahue@uoc.edu>
 */

class AnotaModuleAnnotate extends AnotaModuleBase
{

    /**
     * Index action
     *  - empty function means that it only renders its default template:
     *    templateAnnotate.php
     */
    public function executeIndex()
    {        
    }

    /**
     * Form action
     * - validates and processes submited form
     */
    public function executeForm()
    {
        // validates form
        $values = $this->validateForm();
        if (is_array($values))
        {
            //
            // validation passed
            // 
            
            // set templateResults 
            $this->setTemplate('templateResults.php');

            //
            // configures and executes de Bioinformatic Protocol
            //
            $protocol = new AnotaProtocol($this->config, $values);
            $protocol->execute();
            
            //
            // show results
            //
            $this->results = $protocol;
        } else
        {
            //
            // validation failed
            //
            
            // set session errors
            $this->config->getUser()->setErrors($this->errors);
            
            // go back to Index action
            header('Location: index.php?module=Annotate&action=Index');
        }
    }

    /**
     * Validate form and returns validated data or false if validation fails.
     * 
     * @return array or false
     */
    protected function validateForm()
    {
        // array to acumulate options
        $options = array();

        //
        // validate display options
        //
        $display_options = $this->validateDisplayOptions();
        if (is_array($display_options))
        {
            $options = array_merge($options, $display_options);
        } else
        {
            return false;
        }

        //
        // validate output options
        //
        $output_options = $this->validateOutputOptions();
        if (is_array($output_options))
        {
            $options = array_merge($options, $output_options);
        } else
        {
            return false;
        }

        //
        // validate strand options
        //
        $strand_options = $this->validateStrandOptions();
        if (is_array($strand_options))
        {
            $options = array_merge($options, $strand_options);
        } else
        {
            return false;
        }

        //
        // validate engine options
        //
        $engine_options = $this->validateEngineOptions();
        if (is_array($engine_options))
        {
            $options = array_merge($options, $engine_options);
        } else
        {
            return false;
        }

        //
        // validate param file options
        //
        $paramfile_options = $this->validateParamfileOptions();
        if (is_array($paramfile_options))
        {
            $options = array_merge($options, $paramfile_options);
        } else
        {
            return false;
        }

        //
        // validate input file
        //
        $input_file = $this->validateInputfile();
        if (is_array($input_file))
        {
            $values = array();
            $values['options'] = $options;
            $values['input_file'] = $input_file;
        } else
        {
            return false;
        }

        //
        // return vaidated data
        //
        return $values;
    }

    /**
     * Validate display options
     * 
     * @return array()
     */
    protected function validateDisplayOptions()
    {
        $values = array();
        if (isset($_POST['display_option']))
        {
            $display_option = $_POST['display_option'];
            foreach ($display_option as $key => $value)
            {
                // $value can not be null
                // $key must be 1 character lenght
                // $key must exists in $this->config->getDisplayOptions
                if ($value && strlen($key) == 1 && array_key_exists($key, $this->config->getDisplayOptions()))
                {
                    $values[$key] = '-' . $key;
                } else
                {
                    $this->errors['display_option'][$key] = "Invalid display option ($key).";
                }
            }
        }
        return $values;
    }

    /**
     * validate output options
     * 
     * @return array()
     */
    protected function validateOutputOptions()
    {
        $values = array();
        $output_option = $_POST['output_option'];
        
        // output_option may be null, but...
        // if it exists, it must be one of 'GXMm'.
        if ($output_option == '' || ($output_option != "" && strpos('GXMm', $output_option) !== false))
        {
            if (strlen($output_option) > 0)
            {
                $values['output_option'] = '-' . $output_option;
            }
        } else
        {
            $this->errors['output_option'] = 'Invalid output option (' . $output_option . ').';
        }

        return $values;
    }

    /**
     * validate starnd options
     * 
     * @return array()
     */
    protected function validateStrandOptions()
    {
        $values = array();
        $strand_options = $_POST['strand_options'];
        
        // strand option may be null, but...
        // if it exists, it must be one of 'WC'
        if ($strand_options == '' || ($strand_options != "" && strpos('WC', $strand_options) !== false))
        {
            if (strlen($strand_options) > 0)
            {
                $values['strand_options'] = '-' . $strand_options;
            }
        } else
        {
            $this->errors['strand_options'] = 'Invalid strand option.';
        }

        return $values;
    }

    /**
     * validate engine options
     * 
     * @return array()
     */
    protected function validateEngineOptions()
    {
        $values = array();
        $engine_options = $_POST['engine_options'];
        
        // engine option must be one of 'oFOZ'
        if ($engine_options != "" && strpos('oFOZ', $engine_options) !== false)
        {
            if (strlen($engine_options) > 0)
            {
                $values['engine_options'] = '-' . $engine_options;
            }
        } else
        {
            $this->errors['engine_options'] = 'Invalid engine option.';
        }

        return $values;
    }

    /**
     * validate param file options
     * 
     * @return array
     */
    protected function validateParamfileOptions()
    {
        if (!isset($_POST['param_option']))
        {
            $this->errors['param_option'] = 'Paramfile option not found.';
            return false;
        }

        //
        // todo list: check that selected param option file exists
        $values = array();
        $values['param_option'] = '-P ' . $this->config->getParamfileDir() . DIRECTORY_SEPARATOR . $_POST['param_option'];

        return $values;
    }

    /**
     * validate input file
     * 
     * @return array()
     */
    protected function validateInputfile()
    {
        // input file is a mandatory
        if ($_FILES["input_file"]["error"] > 0)
        {
            $this->errors['input_file'] = "Error " . $_FILES["input_file"]["error"] . ": Input file is a mandatory!";
            return false;
        }

        // store information of uploaded file
        $values = array();
        $values['tmp_name'] = $_FILES["input_file"]["tmp_name"];
        $values['name'] = $_FILES["input_file"]["name"];
        $values['type'] = $_FILES["input_file"]["type"];
        $values['size'] = $_FILES["input_file"]["size"];

        return $values;
    }

}